from twisted.internet import reactor, protocol, stdio
from Location import *
import time
import sys
from twisted.protocols import basic
from sys import stdout
import thread

dispatcher = {}
request = {}
test_sequence = []
test_state = 0
user_seq = 0
	
def Send_RegistSyn(client) :	
	global user_seq
	req = RegistSyn()	
	req.seq = user_seq
	client.send(req)
	print '============================================================'
	print 'Send_RegistSyn'	
	print '============================================================'
	
	
def Read_RegistAck(client, recv_data) :
	ack = RegistAck()
	ack.Load(recv_data)
	print '============================================================'
	print 'Read_RegistAck'	
	print '============================================================'
	Send_ChatSyn(client, 1000, 'AA')
	
def Send_UnRegistSyn(client) :	
	global user_seq
	req = UnRegistSyn()
	req.seq = user_seq
	client.send(req)
	print '============================================================'
	print 'Send_UnRegistSyn'	
	print '============================================================'
	
def Read_UnRegistAck(client, recv_data) :	
	ack = RegistAck()
	ack.Load(recv_data)
	print '============================================================'
	print 'Read_UnRegistAck'
	print '============================================================'
	time.sleep(1)
	Send_RegistSyn(client)


		
def Send_ChatSyn(client, receiver, msg):
	global user_seq
	req = ChatSyn()
	req.sender_seq = user_seq
	req.receiver_seq = receiver
	req.msgs = msg
	client.send(req)
	print '============================================================'
	print 'Send_ChatSyn'	
	print '============================================================'
	
	
def Read_ChatSyn(client, recv_data) :	
	ack = ChatSyn()
	ack.Load(recv_data)
	print '============================================================'
	print 'Read_ChatSyn'	
	print '============================================================'
	Send_RecallSyn(client, 10000)
	
def Read_ChatAck(client, recv_data) :	
	ack = ChatSyn()
	ack.Load(recv_data)
	print '============================================================'
	print 'Read_ChatAck'	
	print '============================================================'
	Send_RecallSyn(client, 10000)

def Send_RecallSyn(client, receiver) :
	global user_seq
	req = RecallSyn()
	req.sender_seq = user_seq
	req.receiver_seq = receiver
	req.ip = '127.0.0.1'
	req.port = 20001
	client.send(req)	
	print '============================================================'
	print 'Send_RecallSyn'	
	print '============================================================'
	
def Read_RecallSyn(client, recv_data) :
	ack = RecallSyn()
	ack.Load(recv_data)
	print '============================================================'
	print 'Read_RecallSyn'	
	print '============================================================'
	Send_UnRegistSyn(client)
	
def Read_RecallAck(client, recv_data) :
	ack = RecallAck()
	ack.Load(recv_data)
	print '============================================================'
	print 'Read_RecallAck'	
	print '============================================================'
	Send_UnRegistSyn(client)
	
test_sequence.append(Send_RegistSyn)
test_sequence.append(Send_UnRegistSyn)

request[RegistSyn.MSG_ID] = Send_RegistSyn
request[UnRegistSyn.MSG_ID] = Send_UnRegistSyn
request[ChatSyn.MSG_ID] = Send_ChatSyn
request[RecallSyn.MSG_ID] = Send_RecallSyn

dispatcher[RegistAck.MSG_ID] = Read_RegistAck
dispatcher[UnRegistAck.MSG_ID] = Read_UnRegistAck
dispatcher[ChatSyn.MSG_ID] = Read_ChatSyn
dispatcher[ChatAck.MSG_ID] = Read_ChatAck
dispatcher[RecallSyn.MSG_ID] = Read_RecallSyn
dispatcher[RecallAck.MSG_ID] = Read_RecallAck

def console(threadName, client) :
	while True :
		value = input('msg id :')
		if (value == 501):
			receiver = input('user_seq :')
			Send_UserInfoSyn(client, receiver)
		elif (value == 503):
			user_seq = input('user_seq :')
			char_seq = input('char_seq :')
			Send_CharInfoSyn(client, user_seq, char_seq)
		elif (value == 505):
			user_seq = input('user_seq :')
			char_seq = input('char_seq :')
			Send_FlushCharacterInfoSyn(client, user_seq, char_seq)
		elif (value == 507):
			user_seq = input('user_seq :')
			Send_FlushUserInfoSyn(client, user_seq)
		elif (value == 509):
			user_seq = input('user_seq :')
			slot_seq = input('slot_seq :')
			Send_FlushUserSlotInfoSyn(client, user_seq, slot_seq)
		elif (value == 511):
			user_seq = input('user_seq :')			
			Send_RemoveUser(client, user_seq)

class Client(protocol.Protocol): 
	recv_data = ''	
	def connectionMade(self): 
		global test_sequence, test_state, user_seq		
		Send_RegistSyn(self)

	def connectionLost(self, reason): 	
		print "connection lost" 

	def dataReceived(self, data) :
		# length of total(include header) : 4byte
		# tag_idl : 4byre
		# data 
		self.recv_data += data
		while len(self.recv_data) :
			global dispatcher, test_sequence, test_state
			if(len(self.recv_data) < 6) :
				print 'received data size is under \'length size\''
				break
		
			recv_bytes_tobe = int(struct.unpack('h', self.recv_data[1:3])[0]) + 3
			if(len(self.recv_data) < recv_bytes_tobe) :
				print 'received data size is under \'total size\''
				break;

			tag_id = struct.unpack('h', self.recv_data[4:6])[0]; 
			recv_data = self.recv_data[6:recv_bytes_tobe] 
			self.recv_data = self.recv_data[recv_bytes_tobe:]
			#print 'tag_id : ' + str(tag_id)
			test_state += 1
			
			dispatcher[tag_id](self, recv_data)
			#console(self)
			#print 'test_state : ' + str(test_state)
			#if test_state < len(test_sequence) :
				#test_sequence[test_state](self)
			
	def send(self, msg) :
		data = msg.Store()
		send_data  = struct.pack('B', 0xff)
		send_data += struct.pack('h', 3 + len(data))
		send_data += struct.pack('b', 0)
		send_data += struct.pack('h', msg.MSG_ID)
		send_data += data
		self.transport.write(send_data)		

class ClientFactory(protocol.ClientFactory): 
	protocol = Client 
	def clientConnectionFailed(self, connector, reason): 
		print "Connection failed - goodbye!" 
		reactor.stop() 
	def clientConnectionLost(self, connector, reason): 
		print "Connection lost - goodbye!" 
		reactor.stop() # this connects the protocol to a server runing on port 8000 

def main():
	global user_seq	
	user_seq = int(sys.argv[1])

	f = ClientFactory()
	reactor.connectTCP("localhost", 20001, f)
	reactor.run()

if __name__ == '__main__': 
	main() 
